package com.jeesite.modules.isys.common.aop.dict;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeesite.common.entity.DataEntity;
import com.jeesite.modules.isys.common.aop.check.PARSE;
import com.jeesite.modules.isys.common.entity.MyPage;
import com.jeesite.modules.isys.common.entity.Res;
import com.jeesite.modules.isys.common.entity.Result;
import org.apache.commons.lang3.math.NumberUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 小野喵
 * @version 1.0
 * @description: TODO
 * @date 2023/9/26 13:16
 */
@Component
public class DictUtils {
    //根据值替换为标签
    public    String dictLabel(String key, String value) {
        String dictLabel = com.jeesite.modules.sys.utils.DictUtils.getDictLabel(key, value, value);
        return dictLabel;
    }

    //根据标签替换为值
    public  String dictValue(String key, String label) {
        String dictValue = com.jeesite.modules.sys.utils.DictUtils.getDictValue(key, label, label);
        return dictValue;
    }

    public static boolean isContainChinese(String str) {

        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }


    //判断参数是否需要拦截
    Boolean checkArgInter(Object object) {
        Boolean flag = false;

        if (object == null){
            return false;
        }
        if (object instanceof DataEntity) {
            return true;
        }

        if (object instanceof String) {
            return flag;
        }


        if (object instanceof Res) {
            return true;
        }


        if (object instanceof Page) {
            return true;
        }

        if (object instanceof List) {
            return true;
        }

        if (object instanceof Map) {
            return true;
        }


        if (object.getClass().getAnnotation(TableName.class)!=null){
            return  true;
        }
        return flag;
    }


    //判断是否需要拦截
    Boolean checkResultInter(Object object) {
        Boolean flag = false;

        if (object instanceof String) {
            return flag;
        }


        if (object instanceof Res) {
            return true;
        }


        if (object instanceof Page) {
            return true;
        }

        if (object instanceof List) {
            return true;
        }

        if (object instanceof Map) {
            return true;
        }

        if (object instanceof MyPage) {
            return true;
        }

        if (object instanceof Result) {
            return true;
        }

        return flag;
    }



    //解析对象判断dict
    public Object parseObj(Object obj, PARSE parse) throws Exception {

        if (obj==null){
            return obj;
        }
        if (obj instanceof Res) {
            obj = execRes(obj, parse);
        } else if (obj instanceof List) {
            obj = execList(obj, parse);
        } else if (obj instanceof Map) {
            obj = execMap(obj, parse);
        } else if (obj instanceof Page) {
            List list = ((Page) obj).getRecords();
            List execList = (List) execList(list, parse);
            ((Page) obj).setRecords(execList);
        }else  if (obj instanceof  MyPage){
            obj =  execMyPage(obj,parse);
        }else  if (obj instanceof Result){
            obj = execResult(obj, parse);
        }
        else {
            obj = execObj(obj, parse);
        }
        return obj;
    }





    private Object execList(Object arg, PARSE parse) throws Exception {
        List<Object> objectList = new ArrayList<>();
        for (Object obj : (List) arg) {
            Object parsedObj = parseObj(obj, parse);
            objectList.add(parsedObj);
        }
        return objectList;
    }


    //处理Map
    private Object execMap(Object obj, PARSE parse) throws Exception {
        Map map = ((Map) obj);
        Set<Object> set = map.keySet();
        for (Object key : set) {
            Object valueObj = map.get(key);
            Object parsedObj = parseObj(valueObj, parse);
            map.put(key, parsedObj);
        }
        return map;
    }

    //处理MyPage
    private Object execMyPage(Object obj, PARSE parse) throws Exception {
        if (obj == null){
            return obj;
        }

        MyPage page = (MyPage) obj;

        Object list = page.getList();

        Object execList = execList(list, parse);

        ((MyPage) obj).setList(execList);

        return obj;
    }

    //处理Result
    private Object execResult(Object obj, PARSE parse) throws Exception {
        if (obj == null){
            return obj;
        }

        Object data = ((Result) obj).getData();

        Object parsed = parseObj(data, parse);
        ((Result) obj).setData(parsed);

        return obj;
    }

    private Object execObj(Object obj, PARSE parse) throws Exception {
        if (obj == null) {
            return obj;
        }

        Field[] fields = obj.getClass().getDeclaredFields();


        for (Field field : fields) {

            //判断类型

            Boolean flag = checkTpye(field);

            if (!flag) {
                continue;
            }

            field.setAccessible(true);

            if (field.get(obj) == null) {
                continue;
            }

            SysDict dict = field.getAnnotation(SysDict.class);
            if (dict != null) {
                //进行处理
                String key = dict.value();
                String value = String.valueOf(field.get(obj));
                String res = value;
                //判断转换类型
                if (parse == PARSE.ARGS) {
                    //参数类型
                    res = dictValue(key, value);

                    //如果转换好的字典参数值不是为数字的话，即可判断前端传入了错误的字典参数
                    if (!NumberUtils.isParsable(res)){
                        throw new Exception("字典参数不正确,传入值: "+ res);
                    }
                    field.set(obj, res);
                } else if (parse == PARSE.RES) {
                    //结果类型
                    res = dictLabel(key, value);
                    field.set(obj, res);
                }
            }
        }
        return obj;
    }

    private Boolean checkTpye(Field field) {
        Boolean flag = false;


        if (field.getType() == String.class || field.getType() == Integer.class) {
            flag = true;
        }

        return flag;
    }


    //处理Res
    private Object execRes(Object obj, PARSE parse) throws Exception {
//        obj =  ((Res) obj);
        Object data = ((Res) obj).getData();
        data = parseObj(data, parse);
        ((Res) obj).setData(data);
        return obj;
    }

}
